/**
 * Copyright 2019 吉鼎科技.

 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package cn.easyplatform.engine.cmd.list;

import cn.easyplatform.contexts.ListContext;
import cn.easyplatform.contexts.RecordContext;
import cn.easyplatform.contexts.SwiftContext;
import cn.easyplatform.contexts.WorkflowContext;
import cn.easyplatform.dos.FieldDo;
import cn.easyplatform.dos.Record;
import cn.easyplatform.engine.runtime.datalist.DataListUtils;
import cn.easyplatform.entities.helper.EventLogic;
import cn.easyplatform.i18n.I18N;
import cn.easyplatform.interceptor.AbstractCommand;
import cn.easyplatform.interceptor.CommandContext;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.messages.request.ListSelectRequestMessage;
import cn.easyplatform.messages.response.SimpleResponseMessage;
import cn.easyplatform.messages.vos.datalist.ListSelectedRowVo;
import cn.easyplatform.messages.vos.swift.LinkTagVo;
import cn.easyplatform.support.scripting.MappingEngine;
import cn.easyplatform.support.scripting.ScriptEngineFactory;
import cn.easyplatform.type.Constants;
import cn.easyplatform.type.IResponseMessage;
import cn.easyplatform.util.MessageUtils;
import cn.easyplatform.util.RuntimeUtils;

import java.util.List;


/**
 * Actionbox选择记录
 *
 * @author <a href="mailto:davidchen@epclouds.com">littleDog</a> <br/>
 * @since 2.0.0 <br/>
 */
public class SelectCmd extends AbstractCommand<ListSelectRequestMessage> {

    /**
     * @param req
     */
    public SelectCmd(ListSelectRequestMessage req) {
        super(req);
    }

    @Override
    public IResponseMessage<?> execute(CommandContext cc) {
        ListSelectedRowVo srv = req.getBody();
        WorkflowContext ctx = cc.getWorkflowContext();
        ListContext lc = ctx.getList(srv.getId());
        if (lc == null)
            return MessageUtils.dataListNotFound(srv.getId());
        if (lc.getType().equals(Constants.CATALOG)) {
            RecordContext rc = null;
            if (lc.isCustom()) {
                rc = lc.createRecord(srv.getKeys());
            } else {
                rc = lc.getRecord(srv.getKeys());
                if (rc == null) {
                    Record record = DataListUtils.getRecord(cc, lc,
                            srv.getKeys());
                    rc = lc.createRecord(srv.getKeys(), record);
                    rc.setParameter("814", 'R');
                    rc.setParameter("815", Boolean.FALSE);
                    lc.appendRecord(rc);
                }
                if ("U".equals(srv.getCode()))
                    cc.getSync().exclusiveLock(lc.getBean().getTable(), srv.getKeys());
            }
            ctx.getRecord().setParameter("814", srv.getCode());
            if (lc.getBean().getTable()
                    .equals(ctx.getRecord().getParameterAsString("833"))) {
                ctx.getRecord().setData(rc.getData());
                EventLogic el = RuntimeUtils.castTo(cc, ctx.getRecord(),
                        ctx.getParameter("835"));
                if (el != null) {
                    ctx.getRecord().setParameter("808", Constants.ON_LOAD);
                    String result = RuntimeUtils.eval(cc, el, ctx.getRecord());
                    if (!result.equals("0000"))
                        return MessageUtils.byErrorCode(cc, ctx.getRecord(),
                                ctx.getId(), result);
                }
            } else {
                if (Strings.isBlank(lc.getBeforeLogic()))
                    return new SimpleResponseMessage("E019", I18N.getLabel(
                            "datalist.mapping.not.found", lc.getId()));
                RuntimeUtils.eval(cc, lc.getBeforeLogic(), rc, ctx.getRecord());
            }
            for (ListContext c : ctx.getLists()) {
                if (c != lc
                        && (c.getType().equals(Constants.CATALOG) || c
                        .getType().equals(Constants.DETAIL))) {
                    if (Strings.isBlank(c.getHost()))
                        c.clear(0);
                    else
                        c.clear(2);
                }
            }
            return new SimpleResponseMessage();
        } else {
            FieldDo[] data = DataListUtils.getRow(cc, lc, srv.getKeys());
            MappingEngine engine = ScriptEngineFactory.createMappingEngine();
            RecordContext rc = null;
            if (srv.getTarget() == null) {
                rc = ctx.getRecord();
            } else if (srv.getTarget() instanceof ListSelectedRowVo) {// datalist
                ListSelectedRowVo target = (ListSelectedRowVo) srv.getTarget();
                ListContext tlc = ctx.getList(target.getId());
                if (tlc == null)
                    return MessageUtils.dataListNotFound(target.getId());
                rc = tlc.getRecord(target.getKeys());
                if (rc.getParameterAsChar("814") != 'C')
                    rc.setParameter("814", 'U');
                rc.setParameter("815", Boolean.TRUE);
            } else if (srv.getTarget() instanceof LinkTagVo) {// swift
                LinkTagVo lv = (LinkTagVo) srv.getTarget();
                SwiftContext sc = ctx.getSwift(lv.getId());
                rc = sc.get(lv.getName(), lv.getKeys());
                if (rc.getParameterAsChar("814") != 'C')
                    rc.setParameter("814", 'U');
                rc.setParameter("815", Boolean.TRUE);
            }
            List<String> list = engine.eval(cc, rc, data, lc.getBeforeLogic());
            return new SimpleResponseMessage(list.toArray(new String[list
                    .size()]));
        }
    }

    @Override
    public String getName() {
        return "list.Select";
    }
}
